package com.captjack.common.util.http;

import com.captjack.common.util.io.IoCommonUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpMessage;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Capt Jack
 * @date 2018/6/1
 */
public final class HttpRequestUtil {

    /**
     * 默认请求头信息
     */
    private static final Map<String, String> DEFAULT_REQUEST_HEADER = new HashMap<String, String>() {{
        put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
    }};

    /**
     * 请求默认编码格式
     */
    private static final String DEFAULT_CHARSET = "UTF-8";

    public static String httpGetAsString(String url) throws Exception {
        return new String(httpGetByteArray(url, DEFAULT_REQUEST_HEADER), DEFAULT_CHARSET);
    }

    public static String httpPostAsString(String url, Map<String, String> params) throws Exception {
        return new String(httpPostByteArray(url, params, DEFAULT_REQUEST_HEADER), DEFAULT_CHARSET);
    }

    public static String httpGetAsString(String url, String charset) throws Exception {
        return new String(httpGetByteArray(url, DEFAULT_REQUEST_HEADER), charset);
    }

    public static String httpPostAsString(String url, Map<String, String> params, String charset) throws Exception {
        return new String(httpPostByteArray(url, params, DEFAULT_REQUEST_HEADER), charset);
    }

    public static String httpGetAsString(String url, Map<String, String> header, String charset) throws Exception {
        return new String(httpGetByteArray(url, header), charset);
    }

    public static String httpPostAsString(String url, Map<String, String> params, Map<String, String> header, String charset) throws Exception {
        return new String(httpPostByteArray(url, params, header), charset);
    }

    public static byte[] httpGetAsBytes(String url) throws Exception {
        return httpGetByteArray(url, DEFAULT_REQUEST_HEADER);
    }

    public static byte[] httpPostAsBytes(String url, Map<String, String> params) throws Exception {
        return httpPostByteArray(url, params, DEFAULT_REQUEST_HEADER);
    }

    public static byte[] httpGetAsBytes(String url, Map<String, String> header) throws Exception {
        return httpGetByteArray(url, header);
    }

    public static byte[] httpPostAsBytes(String url, Map<String, String> params, Map<String, String> header) throws Exception {
        return httpPostByteArray(url, params, header);
    }

    /**
     * 发送http-get请求，将返回结果作为字节数组返回
     *
     * @param url    请求地址
     * @param header 请求头信息
     * @return 字节数组
     * @throws Exception 异常
     */
    private static byte[] httpGetByteArray(String url, Map<String, String> header) throws Exception {
        // 返回结果
        CloseableHttpResponse response = null;
        // 实体
        HttpEntity httpEntity = null;
        try {
            CloseableHttpClient httpClient = HttpConnectionPollManager.HTTP.getHttpsClient();
            // get请求
            HttpGet httpGet = new HttpGet(url);
            // 添加请求头信息
            addRequestHeader(httpGet, header);
            // 执行请求
            response = httpClient.execute(httpGet);
            // 获取请求结果
            httpEntity = response.getEntity();
            // 返回请求结果
            return EntityUtils.toByteArray(httpEntity);
        } finally {
            if (httpEntity != null) {
                EntityUtils.consume(httpEntity);
            }
            IoCommonUtil.closeStream(response);
        }
    }

    /**
     * 发送http-post请求，将返回结果作为字节数组返回
     *
     * @param url    请求地址
     * @param params 请求参数
     * @param header 请求头信息
     * @return 字节数组
     * @throws Exception 异常
     */
    private static byte[] httpPostByteArray(String url, Map<String, String> params, Map<String, String> header) throws Exception {
        // 返回结果
        CloseableHttpResponse response = null;
        // 实体
        HttpEntity httpEntity = null;
        try {
            CloseableHttpClient httpClient = HttpConnectionPollManager.HTTP.getHttpsClient();
            // post请求
            HttpPost httpPost = new HttpPost(url);
            // 添加请求头信息
            addRequestHeader(httpPost, header);
            // 拼接参数
            setPostRequestParams(httpPost, params);
            // 执行请求
            response = httpClient.execute(httpPost);
            // 获取请求结果
            httpEntity = response.getEntity();
            // 返回请求结果
            return EntityUtils.toByteArray(httpEntity);
        } finally {
            if (httpEntity != null) {
                EntityUtils.consume(httpEntity);
            }
            IoCommonUtil.closeStream(response);
        }
    }

    /**
     * 设置http的请求头信息
     *
     * @param header 请求头
     */
    private static void addRequestHeader(HttpMessage httpMessage, Map<String, String> header) {
        if (header != null && header.size() > 0) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                httpMessage.addHeader(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * 设置http-post请求参数
     *
     * @param httpPost httpPost请求对象
     * @param params   参数map
     * @throws Exception 异常
     */
    private static void setPostRequestParams(HttpPost httpPost, Map<String, String> params) throws Exception {
        if (params != null && params.size() > 0) {
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            // 设置参数
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            // 清空list
            nameValuePairs.clear();
        }
    }

}
